from django.shortcuts import render

import json


from django.http import JsonResponse
from django.core.exceptions import ObjectDoesNotExist

from api.utils import success_response_with_data, failed_response_with_data, list_response
from api.utils_member import member_level_exist, get_material, member2material_exist, m_ids_in_memberlevel2material
from api.models import MemberLevel, MemberLevel2Material
from api.serializers import MemberLevelSerializer, MemberLevel2MaterialSerializer

from rest_framework import viewsets
from drf_yasg2.utils import swagger_auto_schema
from drf_yasg2 import openapi
from rest_framework.decorators import action

from django.db.models import Q

from api.mylogger import logger

# Create your views here.


class MemberLevelViewSet(viewsets.ModelViewSet):
    table_name = MemberLevel._meta.db_table
    serializer_class = MemberLevelSerializer
    request_body = openapi.Schema(type=openapi.TYPE_OBJECT,
                                  required=['name', 'code', 'desc', 'benefit', 'order', 'status'],
                                  properties={
                                      "name": openapi.Schema(type=openapi.TYPE_STRING, description="名称"),
                                      "code": openapi.Schema(type=openapi.TYPE_STRING, description="编码"),
                                      "desc": openapi.Schema(type=openapi.TYPE_STRING, description="描述"),
                                      "benefit": openapi.Schema(type=openapi.TYPE_STRING, description="受益描述"),
                                      "order": openapi.Schema(type=openapi.TYPE_INTEGER, description="顺序"),
                                      "status": openapi.Schema(type=openapi.TYPE_BOOLEAN, description="状态(1激活，0禁用)"),
                                  }, )

    @swagger_auto_schema(operation_id='添加会员级别', tags=['memberlevel'], request_body=request_body)
    @action(methods=['POST'], detail=False)
    def memberlevel_add(self, request):
        data = json.loads(request.body.decode('utf8'))
        logger.debug(f"data is {data}")
        serializer = MemberLevelSerializer(data=data)
        if serializer.is_valid():
            res = serializer.save()
            res_data = {
                "table_name": self.table_name,
                "id": res.id,
            }
            return success_response_with_data(res_data, msg="新增会员级别成功")
        return JsonResponse(serializer.errors, status=400)

    request_body_mod = openapi.Schema(type=openapi.TYPE_OBJECT,
                                      required=['name', 'code', 'desc', 'benefit', 'order', 'status'],
                                      properties={
                                          "id": openapi.Schema(type=openapi.TYPE_INTEGER, description="内部id"),
                                          "name": openapi.Schema(type=openapi.TYPE_STRING, description="名称"),
                                          "code": openapi.Schema(type=openapi.TYPE_STRING, description="编码"),
                                          "desc": openapi.Schema(type=openapi.TYPE_STRING, description="描述"),
                                          "benefit": openapi.Schema(type=openapi.TYPE_STRING, description="受益描述"),
                                          "order": openapi.Schema(type=openapi.TYPE_INTEGER, description="顺序"),
                                          "status": openapi.Schema(type=openapi.TYPE_BOOLEAN, description="状态(1激活，0禁用)"),
                                      }, )

    @swagger_auto_schema(operation_id='修改会员级别', tags=['memberlevel'], request_body=request_body_mod)
    @action(methods=['POST'], detail=False)
    def memberlevel_mod(self, request):
        data = json.loads(request.body.decode('utf8'))
        db_id = data.get('id', None)
        logger.debug(f"db id is {db_id}")
        if db_id is None:
            return failed_response_with_data(msg="没有id, 修改不了")

        serializer = MemberLevelSerializer(data=data)
        if serializer.is_valid():
            try:
                db_ret = serializer.update(instance=MemberLevel.objects.get(id=db_id), validated_data=data)
                logger.debug(f"db_ret {db_ret}")
                res_data = {
                    "table_name": self.table_name,
                    "id": db_ret.id
                }
                return success_response_with_data(res_data, msg="修改会员级别成功!")
            except ObjectDoesNotExist:
                logger.debug("没有修改记录")
                return failed_response_with_data(msg=self.table_name + f"没有被修改,未发现id为{db_id}的记录")
        return JsonResponse(serializer.errors, status=400)

    @swagger_auto_schema(operation_id='删除会员级别', tags=['memberlevel'], request_body=openapi.Schema(
        type=openapi.TYPE_OBJECT,
        properties={
            "id": openapi.Schema(type=openapi.TYPE_INTEGER, description="会员级别的内部Id"),
        },
    ))
    @action(methods=['POST'], detail=False)
    def memberlevel_del(self, request):
        data = json.loads(request.body.decode('utf8'))
        db_id = data.get('id', None)
        logger.debug(f"material id is {db_id}")
        # qry = Material.objects.filter(id=db_id)
        # print(qry.query)
        deleted_cnt, _ = MemberLevel.objects.filter(id=db_id).delete()
        res_data = {
            "table_name": self.table_name,
            "id": db_id,
            "rows_deleted": deleted_cnt,
            "info": "删除" + str(deleted_cnt) + "条记录!",
        }
        return success_response_with_data(res_data, msg="删除会员级别记录成功!")

    @swagger_auto_schema(operation_id='单个会员级别信息', tags=['memberlevel'], request_body=openapi.Schema(
        type=openapi.TYPE_OBJECT,
        properties={
            "id": openapi.Schema(type=openapi.TYPE_INTEGER, description="会员级别的内部Id"),
        },
    ))
    @action(methods=['POST'], detail=False)
    def memberlevel_one(self, request):
        data = json.loads(request.body.decode('utf8'))
        db_id = data.get('id', None)
        logger.debug(f"package id is {db_id}")
        try:
            qry = MemberLevel.objects.get(id=db_id)
            serializer = MemberLevelSerializer(qry)
            return success_response_with_data(serializer.data, msg="查询会员级别成功!")
        except ObjectDoesNotExist:
            logger.debug("没有发现记录")
            return failed_response_with_data(None, msg=self.table_name + f"未查到id为{db_id}的横幅!")

    @swagger_auto_schema(operation_id='会员级别列表查询', tags=['memberlevel'],
                         method='POST',
                         request_body=openapi.Schema(
                             type=openapi.TYPE_OBJECT,
                             properties={
                                 "query": openapi.Schema(type=openapi.TYPE_STRING, description="会员级别名称的部分信息"),
                             },
                         )
                         )
    @action(methods=['POST'], detail=False)
    def memberlevel_list(self, request):
        data = json.loads(request.body.decode('utf8'))
        query = data.get("query", '')
        try:
            objects = MemberLevel.objects
            if len(query):
                objects = objects.filter(Q(code__icontains=query) | Q(name__icontains=query))
            objects = objects.all()
            total = objects.count()
            rows = objects
            logger.debug(f"rows.query {rows.query}")

        except ObjectDoesNotExist:
            logger.debug("没有发现记录")
            return list_response()

        serializer = MemberLevelSerializer(rows, many=True)
        return list_response(serializer.data, total, None, None, self.table_name)


class Level2MaterialViewSet(viewsets.ModelViewSet):
    table_name = MemberLevel2Material._meta.db_table
    serializer_class = MemberLevel2MaterialSerializer
    request_body_bind = openapi.Schema(type=openapi.TYPE_OBJECT,
                                       required=['level_code', 'material_ids'],
                                       properties={
                                           "level_code": openapi.Schema(type=openapi.TYPE_STRING, description="会员级别的编号"),
                                           "material_ids": openapi.Schema(type=openapi.TYPE_ARRAY, description="资源id列表",
                                                                          items=openapi.Items(type=openapi.TYPE_INTEGER, description="资源id"),
                                                                          ),
                                       }, )

    @swagger_auto_schema(operation_id='给会员级别添加资源', tags=['memberlevel2material'], request_body=request_body_bind)
    @action(methods=['POST'], detail=False)
    def level2material_bind(self, request):
        data = json.loads(request.body.decode('utf8'))
        logger.debug(f"package2material_add, data is {data}")
        level_code = data.get('level_code', '')
        material_ids = data.get('material_ids', [])
        if not member_level_exist(level_code):
            return failed_response_with_data(msg=f"编号为{level_code}的会员级别不存在！")

        logger.debug(f'material_ids is {material_ids}')

        res_ids = []
        for material_id in material_ids:
            if member2material_exist(level_code, material_id):
                logger.debug(f'绑定记录已经存在 package2material  level_code:{level_code}, material_id:{material_id}')
                continue
            add_dict = {
                "level_code": level_code,
                "material_id": material_id,
            }
            serializer = MemberLevel2MaterialSerializer(data=add_dict)
            if serializer.is_valid():
                try:
                    res = serializer.save()
                    print("res is", res)
                    res_ids.append(res.id)
                except Exception as e:
                    print('Package2MaterialSerializer 存表失败！' + str(e))
            else:
                print("Package2MaterialSerializer data not valid", add_dict)

        res_data = {
            "table_name": self.table_name,
            "ret_ids": res_ids,
        }
        return success_response_with_data(res_data, msg="给会员级别添加资源成功")

    request_body_unbind = openapi.Schema(type=openapi.TYPE_OBJECT,
                                         required=['level_code', 'material_ids'],
                                         properties={
                                             "level_code": openapi.Schema(type=openapi.TYPE_STRING, description="会员级别的编号"),
                                             "material_ids": openapi.Schema(type=openapi.TYPE_ARRAY, description="资源id列表",
                                                                            items=openapi.Items(type=openapi.TYPE_INTEGER, description="资源id"),
                                                                            ),
                                         }, )

    @swagger_auto_schema(operation_id='给会员级别解绑资源-根据资源id列表', tags=['memberlevel2material'], request_body=request_body_unbind)
    @action(methods=['POST'], detail=False)
    def level2material_unbind(self, request):
        data = json.loads(request.body.decode('utf8'))
        level_code = data.get('level_code', '')
        material_ids = data.get('material_ids', [])
        if not member_level_exist(level_code):
            return failed_response_with_data(msg=f"编号为{level_code}的会员级别不存在！")

        logger.debug(f'material_ids is {material_ids}')

        deleted_cnt, _ = MemberLevel2Material.objects.filter(level_code=level_code).filter(material_id__in=material_ids).delete()
        res_data = {
            "table_name": self.table_name,
            "level_code": level_code,
            "material_ids": material_ids,
            "rows_deleted": deleted_cnt,
            "info": "删除" + str(deleted_cnt) + "条记录!",
        }
        return success_response_with_data(res_data, msg="给会员级别解绑资源成功!")

    request_body_unbind = openapi.Schema(type=openapi.TYPE_OBJECT,
                                         required=['level_code', 'material_ids'],
                                         properties={
                                             "level_code": openapi.Schema(type=openapi.TYPE_STRING, description="会员级别的编号"),
                                             "material_type": openapi.Schema(type=openapi.TYPE_STRING, description="资源类型"),
                                         }, )

    @swagger_auto_schema(operation_id='给会员级别解绑资源-根据资源类型', tags=['memberlevel2material'], request_body=request_body_unbind)
    @action(methods=['POST'], detail=False)
    def level2material_unbind_onetype(self, request):
        data = json.loads(request.body.decode('utf8'))
        level_code = data.get('level_code', '')
        material_type = data.get('material_type', '')
        if not member_level_exist(level_code):
            return failed_response_with_data(msg=f"编号为{level_code}的会员级别不存在！")
        if material_type.strip() == '':
            return failed_response_with_data(msg=f"请提供material_type！")
        logger.debug(f'material_type is {material_type}')
        material_ids = m_ids_in_memberlevel2material(level_code, material_type)
        logger.debug(f'material_ids is {material_ids}')
        deleted_cnt, _ = MemberLevel2Material.objects.filter(level_code=level_code).filter(material_id__in=material_ids).delete()
        res_data = {
            "table_name": self.table_name,
            "level_code": level_code,
            "material_ids": material_ids,
            "material_type": material_type,
            "rows_deleted": deleted_cnt,
            "info": "删除" + str(deleted_cnt) + "条记录!",
        }
        return success_response_with_data(res_data, msg="给会员级别解绑成功!")

    @swagger_auto_schema(operation_id='会员级别的资源列表查询', tags=['memberlevel2material'],
                         method='POST',
                         request_body=openapi.Schema(
                             type=openapi.TYPE_OBJECT,
                             required=['level_code'],
                             properties={
                                 "level_code": openapi.Schema(type=openapi.TYPE_STRING, description="会员级别的编号"),
                                 "material_type": openapi.Schema(type=openapi.TYPE_STRING, description="material_type"),
                             },
                         )
                         )
    @action(methods=['POST'], detail=False)
    def level2material_list(self, request):
        data = json.loads(request.body.decode('utf8'))
        material_type = data.get("material_type", '')
        level_code = data.get("level_code", '')
        if level_code == '':
            return failed_response_with_data(msg=f"请提供level_code参数！")

        try:
            objects = MemberLevel2Material.objects
            if level_code != '':
                objects = objects.filter(level_code=level_code)
            objects = objects.all()
            total = objects.count()
            rows = objects
            logger.debug(f"rows.query {rows.query}")

        except ObjectDoesNotExist:
            logger.debug("没有发现记录")
            return list_response()

        member2material_list = MemberLevel2MaterialSerializer(rows, many=True).data
        new_member2material_list = []
        for index in range(len(member2material_list)):
            row = member2material_list[index]
            material_id = row["material_id"]
            material_obj = get_material(material_id)
            if material_id is None:
                continue
            print(f"material_id id is {material_id}, material_obj is {material_obj}")
            if len(material_obj) == 0:
                continue
            if material_type != '' and material_obj['material_type'] != material_type:
                continue
            row['material'] = material_obj
            new_member2material_list.append(row)

        return list_response(new_member2material_list, total, None, None, self.table_name)

